package yyds.sniarbtej.transformer;

import yyds.sniarbtej.Environment;
import yyds.sniarbtej.LicenseManager;
import yyds.sniarbtej.MyTransformer;
import yyds.sniarbtej.transformer.dbeaver.LicenseKey;
import yyds.sniarbtej.transformer.dbeaver.LicenseValidator;
import yyds.sniarbtej.transformer.dbeaver.PublicServiceClient;
import yyds.sniarbtej.transformer.dbvisualizer.SkipSignature;
import yyds.sniarbtej.transformer.intellij.*;
import yyds.sniarbtej.utils.DebugUtil;

import java.io.File;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;

public class TransformerManager {

    public static void createTransformers(Environment environment) {
        MyTransformer transformers = new MyTransformer(environment);
        /* JetBrains */
        transformers.addTransformer(new Decrypt());
        transformers.addTransformer(new BlockValidationHost());
        transformers.addTransformer(new BlockHost());
        transformers.addTransformer(new RemoveAgentVMArgs());
        transformers.addTransformer(new HideAgentStrings());
        transformers.addTransformer(new HideAgent());
        transformers.addTransformer(new ChangeExpirationDate());
        transformers.addTransformer(new CreateLicenses());
        /* DBeaver */
        transformers.addTransformer(new LicenseKey());
        transformers.addTransformer(new LicenseValidator());
        transformers.addTransformer(new PublicServiceClient());
        /* DBVisualizer */
        transformers.addTransformer(new SkipSignature());
        Instrumentation instr = environment.getInstrumentation();
        instr.addTransformer(transformers, true);
        Set<String> transformedClass = transformers.getTransformedClass();

        for (Class<?> aClass : instr.getAllLoadedClasses()) {
            String name = aClass.getName();
            if (transformedClass.contains(name)) {
                try {
                    instr.retransformClasses(aClass);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            DebugUtil.log("Create Licenses");
            createLicenses(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void createLicenses(String configPath) {
        String platformPrefix = System.getProperty("idea.platform.prefix", "idea").toLowerCase();
        System.out.println("platformPrefix: " + platformPrefix);
        if (configPath == null) {
            String producer = "JetBrains";
            if (platformPrefix.equals("androidstudio")) {
                producer = "Google";
            }

            String os = System.getProperty("os.name").toLowerCase();
            String home = System.getProperty("user.home");
            String path = "";
            if (os.contains("win")) {
                path = Paths.get(home, "AppData", "Roaming", producer).toString();
            } else if (!os.contains("mac") && !os.contains("darwin")) {
                if (os.contains("nux")) {
                    path = Paths.get(home, ".config", producer).toString();
                }
            } else {
                path = Paths.get(home, "Library", "Application Support", producer).toString();
            }

            String pathsSelector = System.getProperty("idea.paths.selector");
            if (pathsSelector == null) {
                return;
            }
            configPath = Paths.get(path, pathsSelector).toString();
        }

        Path path = Paths.get(configPath);
        System.out.println("configPath: " + configPath);
        String productHome = System.getProperty(platformPrefix + ".config.path");
        if (!configPath.equals(productHome)) {
            if (!Files.exists(path)) {
                return;
            }
        } else if (!Files.exists(path)) {
            try {
                Files.createDirectories(path);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        if (Files.exists(path)) {
            if (platformPrefix.equals("python")) {
                platformPrefix = "pycharm";
            }
            File lic = new File(configPath, platformPrefix + ".key");
            DebugUtil.log("License Key: " + lic);
            LicenseManager.checkLicenseFile(lic);
            File[] licenseFiles = new File(configPath).listFiles((dir, name) -> name.startsWith("plugin_") && name.endsWith(".license"));
            if (licenseFiles != null) {
                for (File license : licenseFiles) {
                    DebugUtil.log("[XXX]License: " + license);
                    LicenseManager.checkLicenseFile(license);
                }
            }
        }
    }

}
